home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / lists / mint / l_0799 / 685 / asmtrans.zoo / trutil.c < prev   
Encoding:
C/C++ Source or Header  |  1993-12-05  |  7.6 KB  |  435 lines

  1. /* asmtrans translator
  2.    Copyright 1992,1993 Eric R. Smith
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 1, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. #define YYSTYPE char *
  20. #include "asmtrans.h"
  21. #include "asmtab.h"
  22.  
  23. #define QUOTESYM '"'
  24. #define CMDSYM '%'
  25.  
  26. FILE *infile, *outfile;
  27. extern YYSTYPE yylval;
  28.  
  29. #define MAXNEST 10
  30. int hidecnt = 0;
  31. int ifstack[MAXNEST], ifstkptr;
  32.  
  33. void emit(s)
  34.     char *s;
  35. {
  36.     if (hidecnt == 0)
  37.         fputs(s, outfile);
  38.     free(s);
  39. }
  40.  
  41. char *concat(s1, s2)
  42.     char *s1, *s2;
  43. {
  44.     size_t siz = strlen(s1) + strlen(s2) + 1;
  45.     char *r;
  46.  
  47.     r = malloc(siz);
  48.     if (!r) return 0;
  49.  
  50.     strcpy(r, s1);
  51.     strcat(r, s2);
  52.     return r;
  53. }
  54.  
  55. char *concat3(s1, s2, s3)
  56.     char *s1, *s2, *s3;
  57. {
  58.     size_t siz = strlen(s1) + strlen(s2) + strlen(s3) + 1;
  59.     char *r;
  60.  
  61.     r = malloc(siz);
  62.     if (!r) return 0;
  63.  
  64.     strcpy(r, s1);
  65.     strcat(r, s2);
  66.     strcat(r, s3);
  67.     return r;
  68. }
  69.  
  70. char *concat4(s1, s2, s3, s4)
  71.     char *s1, *s2, *s3, *s4;
  72. {
  73.     size_t siz = strlen(s1) + strlen(s2) + strlen(s3) + strlen(s4) + 1;
  74.     char *r;
  75.  
  76.     r = malloc(siz);
  77.     if (!r) return 0;
  78.  
  79.     strcpy(r, s1);
  80.     strcat(r, s2);
  81.     strcat(r, s3);
  82.     strcat(r, s4);
  83.     return r;
  84. }
  85.  
  86. char *concat5(s1, s2, s3, s4, s5)
  87.     char *s1, *s2, *s3, *s4, *s5;
  88. {
  89.     size_t siz = strlen(s1) + strlen(s2) + strlen(s3)
  90.             + strlen(s4) + strlen(s5) + 1;
  91.     char *r;
  92.  
  93.     r = malloc(siz);
  94.     if (!r) return 0;
  95.  
  96.     strcpy(r, s1);
  97.     strcat(r, s2);
  98.     strcat(r, s3);
  99.     strcat(r, s4);
  100.     strcat(r, s5);
  101.     return r;
  102. }
  103.  
  104. char *concat6(s1, s2, s3, s4, s5, s6)
  105.     char *s1, *s2, *s3, *s4, *s5, *s6;
  106. {
  107.     size_t siz = strlen(s1) + strlen(s2) + strlen(s3)
  108.             + strlen(s4) + strlen(s5) + strlen(s6) + 1;
  109.     char *r;
  110.  
  111.     r = malloc(siz);
  112.     if (!r) return 0;
  113.  
  114.     strcpy(r, s1);
  115.     strcat(r, s2);
  116.     strcat(r, s3);
  117.     strcat(r, s4);
  118.     strcat(r, s5);
  119.     strcat(r, s6);
  120.     return r;
  121. }
  122.  
  123. char *concat8(s1, s2, s3, s4, s5, s6, s7, s8)
  124.     char *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8;
  125. {
  126.     size_t siz = strlen(s1) + strlen(s2) + strlen(s3)
  127.             + strlen(s4) + strlen(s5) + strlen(s6) 
  128.             + strlen(s7) + strlen(s8) + 1;
  129.     char *r;
  130.  
  131.     r = malloc(siz);
  132.     if (!r) return 0;
  133.  
  134.     strcpy(r, s1);
  135.     strcat(r, s2);
  136.     strcat(r, s3);
  137.     strcat(r, s4);
  138.     strcat(r, s5);
  139.     strcat(r, s6);
  140.     strcat(r, s7);
  141.     strcat(r, s8);
  142.     return r;
  143. }
  144.  
  145. char *concat9(s1, s2, s3, s4, s5, s6, s7, s8, s9)
  146.     char *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9;
  147. {
  148.     size_t siz = strlen(s1) + strlen(s2) + strlen(s3)
  149.             + strlen(s4) + strlen(s5) + strlen(s6) 
  150.             + strlen(s7) + strlen(s8) + strlen(s9) + 1;
  151.     char *r;
  152.  
  153.     r = malloc(siz);
  154.     if (!r) return 0;
  155.  
  156.     strcpy(r, s1);
  157.     strcat(r, s2);
  158.     strcat(r, s3);
  159.     strcat(r, s4);
  160.     strcat(r, s5);
  161.     strcat(r, s6);
  162.     strcat(r, s7);
  163.     strcat(r, s8);
  164.     strcat(r, s9);
  165.     return r;
  166. }
  167.  
  168.  
  169. static int is_word_sym(c)
  170.     int c;
  171. {
  172.     if (c == '.' || (c >= '0' && c <= '9')) return 1;
  173.     if (c >= 'a' && c <= 'z') return 1;
  174.     if (c >= 'A' && c <= 'Z') return 1;
  175.     if (c == '_') return 1;
  176.     return 0;
  177. }
  178.  
  179. typedef struct wordtab {
  180.     char *word;
  181.     char *defn;
  182.     struct wordtab *next;
  183. } WORDTAB;
  184.  
  185. WORDTAB *globaltab;
  186.  
  187. void
  188. do_define(word, defn)
  189.     char *word, *defn;
  190. {
  191.     WORDTAB *w;
  192.  
  193.     w = malloc(sizeof(WORDTAB));
  194.     if (!w) return;
  195.     w->word = strdup(word);
  196.     w->defn = strdup(defn);
  197.     w->next = globaltab;
  198.     globaltab = w;
  199. }
  200.  
  201. /*
  202.  * if we were actually using this program for
  203.  * large things, we would use a hash table
  204.  * to speed up the table lookup; but for the
  205.  * uses we have, there aren't likely to be
  206.  * many defines
  207.  */
  208.  
  209. char *
  210. wordlookup(which)
  211.     char *which;
  212. {
  213.     WORDTAB *w;
  214.  
  215.     for (w = globaltab; w; w = w->next) {
  216.         if (!strcmp(which, w->word)) {
  217.             return strdup(w->defn);
  218.         }
  219.     }
  220.     return strdup(which);
  221. }
  222.  
  223. void
  224. do_ifdef(which)
  225.     char *which;
  226. {
  227.     int output = 0;
  228.     WORDTAB *w;
  229.  
  230.     for (w = globaltab; w; w = w->next) {
  231.         if (!strcmp(which, w->word)) {
  232.             output = 1;
  233.             break;
  234.         }
  235.     }
  236.     if (ifstkptr < MAXNEST) {
  237.         ifstack[ifstkptr++] = output;
  238.         if (!output)
  239.             hidecnt++;
  240.     } else {
  241.         ifstkptr++;
  242.         yyerror("too many levels of %ifdef");
  243.     }
  244. }
  245.  
  246. void
  247. do_ifndef(which)
  248.     char *which;
  249. {
  250.     int output = 1;
  251.     WORDTAB *w;
  252.  
  253.     for (w = globaltab; w; w = w->next) {
  254.         if (!strcmp(which, w->word)) {
  255.             output = 0;
  256.             break;
  257.         }
  258.     }
  259.     if (ifstkptr < MAXNEST) {
  260.         ifstack[ifstkptr++] = output;
  261.         if (!output)
  262.             hidecnt++;
  263.     } else {
  264.         ifstkptr++;
  265.         yyerror("too many levels of %ifdef");
  266.     }
  267. }
  268.  
  269. void
  270. do_else()
  271. {
  272.     int output;
  273.  
  274.     if (ifstkptr == 0) {
  275.         yyerror("%else without %ifdef");
  276.     } else {
  277.         if (ifstkptr > MAXNEST) return;
  278.     /* if we were outputting, stop */
  279.     /* otherwise, start again */
  280.         output = !ifstack[ifstkptr-1];
  281.         if (output)
  282.             hidecnt--;
  283.         else
  284.             hidecnt++;
  285.         ifstack[ifstkptr-1] = output;
  286.     }
  287. }
  288.  
  289. void
  290. do_endif()
  291. {
  292.     int output;
  293.  
  294.     if (ifstkptr == 0) {
  295.         yyerror("%endif without %ifdef");
  296.     } else {
  297.         ifstkptr--;
  298.         if (ifstkptr >= MAXNEST) return;
  299.  
  300.         output = ifstack[ifstkptr];
  301.         if (!output)
  302.             hidecnt--;
  303.     }
  304. }
  305.  
  306. /* this is a terrible hack to remove the leading
  307.  * '_' from labels...
  308.  */
  309.  
  310. char *
  311. fixupword(w)
  312.     char *w;
  313. {
  314.     if (*w == '_' && syntax == PUREC)
  315.         return strdup(w+1);
  316.     else
  317.         return strdup(w);
  318. }
  319.  
  320.  
  321. static char footext[1024];
  322.  
  323. int
  324. yylex()
  325. {
  326.     int c;
  327.     char *to = footext;
  328.     int cmdword;
  329.     static int saweoln = 1;
  330.  
  331.     c = getc(infile);
  332.  
  333.     if (c < 0) {
  334. doeof:
  335.         saweoln = 1;
  336.         return 0;
  337.     }
  338.     if (c == ';') {
  339. docomment:
  340.         if (syntax == GAS)
  341.             c = '|';
  342.         *to++ = c;
  343.         do {
  344.             c = getc(infile);
  345.             if (c < 0) return 0;
  346.             if (c != '\r')
  347.                 *to++ = c;
  348.         } while (c != '\n');
  349.         *to = 0;
  350.         yylval = strdup(footext);
  351.         saweoln = 1;
  352.         return EOLN;
  353.     }
  354.     if (c == '\n') {
  355. doeoln:
  356.         *to++ = c;
  357.         *to = 0;
  358.         yylval = strdup(footext);
  359.         saweoln = 1;
  360.         return EOLN;
  361.     }
  362.     if (c == CMDSYM && saweoln) {
  363.         cmdword = 1;
  364.         c = getc(infile);
  365.     } else {
  366.         cmdword = 0;
  367.     }
  368.  
  369.     if (c == ' ' || c == '\t' || c == '\r') {
  370.         do {
  371.             if (c == '\r')
  372.                 c = ' ';
  373.             *to++ = c;
  374.             c = getc(infile);
  375.         } while (c == ' ' || c == '\t');
  376.         if (c == '\n') goto doeoln;
  377.         if (c == ';') goto docomment;
  378.         if (!cmdword) {
  379.             ungetc(c, infile);
  380.             *to = 0;
  381.             yylval = strdup(footext);
  382.             return WHITESP;
  383.         } else {
  384.             to = footext;
  385.         }
  386.     }
  387.  
  388.     saweoln = 0;
  389.  
  390.     if (c == QUOTESYM) {
  391.         for(;;) {
  392.             c = getc(infile);
  393.             if (c < 0) goto doeof;
  394.             if (c == QUOTESYM) break;
  395.             *to++ = c;
  396.         }
  397.         *to = 0;
  398.         yylval = strdup(footext);
  399.         return STRING;
  400.     }
  401.     if (is_word_sym(c)) {
  402.         do {
  403.             *to++ = c;
  404.             c = getc(infile);
  405.         } while (is_word_sym(c));
  406.         ungetc(c, infile);
  407.         *to = 0;
  408.         if (cmdword) {
  409.             yylval = footext;
  410.             if (!strcmp(footext, "define")) {
  411.                 return DEFINECMD;
  412.             } else if (!strcmp(footext, "include")) {
  413.                 return INCLUDECMD;
  414.             } else if (!strcmp(footext, "ifdef")) {
  415.                 return IFDEFCMD;
  416.             } else if (!strcmp(footext, "ifndef")) {
  417.                 return IFNDEFCMD;
  418.             } else if (!strcmp(footext, "else")) {
  419.                 return ELSECMD;
  420.             } else if (!strcmp(footext, "endif")) {
  421.                 return ENDIFCMD;
  422.             } else {
  423.                 fprintf(stderr, "Unknown command: %s\n", footext);
  424.             }
  425.         }
  426.         yylval = fixupword(footext);
  427.         return WORD;
  428.     }
  429.  
  430.     *to++ = c;
  431.     *to = 0;
  432.     yylval = footext;
  433.     return c;
  434. }
  435.